
<template>

  <div class="container">

    <h1>Todo List</h1>

  
    <!-- pour ajouter une tâche, usage de v model qui écoute le champs et execute la methode ajouterTache-->
    
 
    <div class="input-group">

      <input
        type="text"
        placeholder="Ajouter une tâche..."
        v-model="nouvelleTache"
        @keyup.enter="ajouterTache" 
        
        
      />
<!--evenement oû la touche entrée est appuyer-->
      <button @click="ajouterTache">

        Ajouter

      </button>

    </div>



    <!-- les boutons de filtrages des taches selon leur statuts -->
   

    <div class="filters">

      <button
        @click="changerFiltre('all')"
        :class="{ active: currentFilter === 'all' }"
      >

        Toutes

      </button>

      <button
        @click="changerFiltre('active')"
        :class="{ active: currentFilter === 'active' }"
      >

        Actives

      </button>

      <button
        @click="changerFiltre('completed')"
        :class="{ active: currentFilter === 'completed' }"
      >

        Terminées

      </button>

      <button @click="clearCompleted">

        Supprimer terminées

      </button>

    </div>



    
    <!-- CHARGEMENT des tâches -->
   

    <div
      v-if="loading"
      class="loading"
    >

      Chargement...

    </div>

    <!-- ERREUR -->


    <div
      v-if="error"
      class="error"
    >

      {{ error }}

    </div>



    
    <!-- AUCUNE TÂCHE -->
   
    

    <div
      v-if="!loading && paginatedTasks.length === 0"
      class="empty"
    >

      Aucune tâche trouvée.

    </div>



    <!-- afficher la liste des tâches-->
  
    

    <ul
      v-if="!loading && paginatedTasks.length > 0"
      class="list-group"
    >

      <li
        v-for="task in paginatedTasks"
        :key="task.id"
        class="list-group-item"
      >

        <div class="task-left">

          <input
            type="checkbox"
            :checked="task.status === 'completed'"
            @change="toggleTask(task.id)"
          />

          <span
            class="task-text"
            :class="{

              completed: task.status === 'completed'

            }"
          >

            {{ task.title }}

          </span>

        </div>



        <div class="task-buttons">

          <button
            class="btn-success"
            @click="toggleTask(task.id)"
          >

            {{ task.status === "completed"

                ? "Annuler"

                : "Terminer"

            }}

          </button>

          <button
            class="btn-danger"
            @click="supprimerTask(task.id)"
          >

            Supprimer

          </button>

        </div>

      </li>

    </ul>



    
    <!-- afficher la pagination -->
    

    <div
      v-if="totalPages > 1"
      class="pagination"
    >

      <button
        @click="previousPage"
        :disabled="currentPage === 1"
      >

        ◀ Précédent

      </button>

      <span>

        Page {{ currentPage }}

        /

        {{ totalPages }}

      </span>

      <button
        @click="nextPage"
        :disabled="currentPage === totalPages"
      >

        Suivant ▶

      </button>

    </div>


  </div>

</template>



// Le JS
<script setup>

import { ref, computed,
onMounted } from "vue"

//appel de l'API

const API = "https://jsonplaceholder.typicode.com/todos"

// toutes les variables initialisées

const tasks = ref([])

const nouvelleTache = ref("")

const currentFilter = ref("all")

const currentPage = ref(1)

const itemsPerPage = 10

const loading = ref(false)

const error = ref("")


// CHARGEMENT AU DEMARRAGE


onMounted(() => {

    chargerTaches()

})


// CHARGER LES TACHES

async function chargerTaches() {

    loading.value = true

    error.value = ""

    try {

        const response = await fetch(API)

        if (!response.ok) {

            throw new Error("Impossible de charger les tâches")

        }

        const data = await response.json()

        tasks.value = data.slice(0, 50).map(todo => ({

            id: todo.id,

            title: todo.title,

            status: todo.completed ? "completed" : "active"

        }))

    }

    catch(err){

        error.value = err.message

    }

    finally{

        loading.value = false

    }

}


//fonction pour ajouter une tache 

async function ajouterTache(){

    if(nouvelleTache.value.trim()===""){

        return

    }

    try{

        const response = await fetch(API,{

            method:"POST",

            headers:{

                "Content-Type":"application/json"

            },

            body:JSON.stringify({

                title:nouvelleTache.value,

                completed:false,

                userId:1

            })

        })

        if(!response.ok){

            throw new Error("Erreur lors de l'ajout")

        }

        const todo = await response.json()

        tasks.value.unshift({

            id:todo.id,

            title:todo.title,

            status:"active"

        })

        nouvelleTache.value=""

    }

    catch(err){

        alert(err.message)

    }

}


// TERMINER UNE TACHE


async function toggleTask(id){

    const task = tasks.value.find(

        t=>t.id===id

    )

    if(!task) return

    try{

        await fetch(`${API}/${id}`,{

            method:"PATCH",

            headers:{

                "Content-Type":"application/json"

            },

            body:JSON.stringify({

                completed:task.status!=="completed"

            })

        })

        task.status=

            task.status==="completed"

            ? "active"

            : "completed"

    }

    catch(err){

        alert(err.message)

    }

}

//supression d'une tache

async function supprimerTask(id){

    const confirmation = confirm(

        "Voulez-vous vraiment supprimer cette tâche ?"

    )

    if(!confirmation){

        return

    }

    try{

        await fetch(`${API}/${id}`,{

            method:"DELETE"

        })

        tasks.value = tasks.value.filter(

            task => task.id !== id

        )

    }

    catch(err){

        alert(err.message)

    }

}


// SUPPRIMER LES TERMINEES


async function clearCompleted(){

    const completed = tasks.value.filter(

        task=>task.status==="completed"

    )

    for(const task of completed){

        await supprimerTask(task.id)

    }

}


// FILTRE


function changerFiltre(filter){

    currentFilter.value=filter

}

//
// COMPUTED : FILTRAGE


const filteredTasks = computed(()=>{

    switch(currentFilter.value){

        case "active":

            return tasks.value.filter(

                task=>task.status==="active"

            )

        case "completed":

            return tasks.value.filter(

                task=>task.status==="completed"

            )

        default:

            return tasks.value

    }

})


// COMPUTED : PAGINATION


const totalPages = computed(()=>{

    return Math.max(

        1,

        Math.ceil(

            filteredTasks.value.length/

            itemsPerPage

        )

    )

})

const paginatedTasks = computed(()=>{

    const debut=(currentPage.value-1)

        *itemsPerPage

    const fin=debut+itemsPerPage

    return filteredTasks.value.slice(

        debut,

        fin

    )

})



// PAGINATION


function nextPage(){

    if(currentPage.value<totalPages.value){

        currentPage.value++

    }

}

function previousPage(){

    if(currentPage.value>1){

        currentPage.value--

    }

}



</script>





// le CSS

<style>

*{
    margin:0;
    padding:0;
    box-sizing:border-box;
}

body{

    background:#f5f7fb;

    font-family:'Segoe UI',Tahoma,Geneva,Verdana,sans-serif;

}

.container{

    width:90%;

    max-width:900px;

    margin:40px auto;

    background:#ffffff;

    padding:30px;

    border-radius:12px;

    box-shadow:0 8px 25px rgba(0,0,0,.12);

}

h1{

    text-align:center;

    color:#0d6efd;

    margin-bottom:30px;

}

.input-group{

    display:flex;

    gap:12px;

    margin-bottom:25px;

}

.input-group input{

    flex:1;

    padding:12px;

    border:1px solid #ccc;

    border-radius:8px;

    font-size:16px;

    outline:none;

    transition:.3s;

}

.input-group input:focus{

    border-color:#0d6efd;

    box-shadow:0 0 6px rgba(13,110,253,.3);

}

.input-group button{

    padding:12px 20px;

    border:none;

    border-radius:8px;

    background:#0d6efd;

    color:white;

    cursor:pointer;

    transition:.3s;

}

.input-group button:hover{

    background:#0b5ed7;

}

.filters{

    display:flex;

    justify-content:center;

    gap:10px;

    flex-wrap:wrap;

    margin-bottom:25px;

}

.filters button{

    padding:10px 16px;

    border:none;

    border-radius:6px;

    background:#e9ecef;

    cursor:pointer;

    transition:.3s;

}

.filters button:hover{

    background:#ced4da;

}

.filters button.active{

    background:#0d6efd;

    color:white;

}

.loading{

    text-align:center;

    color:#0d6efd;

    padding:20px;

    font-weight:bold;

}

.error{

    background:#f8d7da;

    color:#842029;

    padding:15px;

    border-radius:8px;

    margin-bottom:20px;

}

.empty{

    text-align:center;

    padding:30px;

    color:#6c757d;

    font-style:italic;

}

.list-group{

    list-style:none;

}

.list-group-item{

    display:flex;

    justify-content:space-between;

    align-items:center;

    padding:15px;

    border-bottom:1px solid #dee2e6;

    transition:.3s;

}

.list-group-item:hover{

    background:#f8f9fa;

}

.task-left{

    display:flex;

    align-items:center;

    gap:12px;

}

.task-text{

    font-size:16px;

}

.completed{

    text-decoration:line-through;

    color:#6c757d;

    opacity:.7;

}

.task-buttons{

    display:flex;

    gap:10px;

}

.task-buttons button{

    border:none;

    border-radius:6px;

    padding:8px 14px;

    cursor:pointer;

    color:white;

    transition:.3s;

}

.btn-success{

    background:#198754;

}

.btn-success:hover{

    background:#157347;

}

.btn-danger{

    background:#dc3545;

}

.btn-danger:hover{

    background:#bb2d3b;

}

.pagination{

    display:flex;

    justify-content:center;

    align-items:center;

    gap:20px;

    margin-top:25px;

}

.pagination button{

    padding:10px 18px;

    border:none;

    border-radius:6px;

    background:#0d6efd;

    color:white;

    cursor:pointer;

}

.pagination button:hover:not(:disabled){

    background:#0b5ed7;

}

.pagination button:disabled{

    background:#adb5bd;

    cursor:not-allowed;

}

.stats{

    display:flex;

    justify-content:space-around;

    margin-top:35px;

    padding:15px;

    border-top:1px solid #dee2e6;

}

.stats p{

    font-size:16px;

}

.stats strong{

    color:#0d6efd;

}

input[type="checkbox"]{

    width:18px;

    height:18px;

    cursor:pointer;

}

button{

    font-size:15px;

}

</style>
